import random
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO
import base64
import os
import uuid
import time
from app.setting import settings

class YanZhengMaAPI:
    def __init__(self):
        # 定义静态资源存储路径
        self.static_dir = f"{settings.STATIC_DIR}/images"
        self.static_path = f"{settings.STATIC_PATH}/images"
        # 确保静态资源目录存在
        os.makedirs(self.static_dir, exist_ok=True)
        
    def handle(self, text: str, type: str = "json"):
        try:
            # 生成验证码图片
            img = self.generate_captcha(text)
            
            # 根据type参数决定返回类型
            if type.lower() == "json":
                # 将处理后的图片转为base64编码
                buffered = BytesIO()
                img.save(buffered, format="PNG")
                img_str = base64.b64encode(buffered.getvalue()).decode()
                
                return {
                    "success": True,
                    "message": "验证码图片生成成功",
                    "data": {
                        "image_base64": f"data:image/png;base64,{img_str}"
                    }
                }
            elif type.lower() == "image":
                # 生成唯一文件名
                filename = f"captcha_{uuid.uuid4().hex}_{int(time.time())}.png"
                file_path = os.path.join(self.static_dir, filename)
                
                # 保存图片到静态资源目录
                img.save(file_path, format="PNG")
                
                # 构建图片URL
                image_url = f"{self.static_path}/{filename}"
                
                return {
                    "success": True,
                    "message": "验证码图片生成成功",
                    "data": {
                        "image_url": image_url
                    }
                }
            else:
                return {
                    "success": False,
                    "message": f"不支持的type参数: {type}，支持的类型为json或image",
                    "data": None
                }
        except Exception as e:
            return {
                "success": False,
                "message": f"生成验证码图片时出错: {str(e)}",
                "data": None
            }
    
    def generate_captcha(self, text):
        """生成验证码图片"""
        # 设置图片尺寸
        width = 120
        height = 50
        
        # 创建新图片
        img = Image.new('RGB', (width, height), color=(255, 255, 255))
        draw = ImageDraw.Draw(img)
        
        try:
            # 尝试加载字体，如果失败则使用默认字体
            font = ImageFont.truetype("Arial", 36)
        except IOError:
            # 使用默认字体
            font = ImageFont.load_default()
        
        # 逐个字符绘制，使每个字符颜色和位置都不同
        char_width_total = 0
        for i, char in enumerate(text):
            # 生成随机颜色
            color = (
                random.randint(0, 200),  # R
                random.randint(0, 200),  # G
                random.randint(0, 200)   # B
            )
            
            # 计算单个字符的尺寸
            try:
                char_width, char_height = font.getsize(char)
            except AttributeError:
                bbox = font.getbbox(char)
                char_width = bbox[2] - bbox[0]
                char_height = bbox[3] - bbox[1]
            
            # 计算基础位置
            base_x = 10 + char_width_total + i * 5  # 字符间距离
            base_y = (height - char_height) // 2
            
            # 添加随机偏移
            offset_x = random.randint(-5, 5)
            offset_y = random.randint(-5, 5)
            
            # 最终位置
            position = (base_x + offset_x, base_y + offset_y)
            
            # 绘制文本
            draw.text(position, char, font=font, fill=color)
            
            # 累加字符宽度
            char_width_total += char_width
        
        # 添加干扰线
        for i in range(5):
            x1 = random.randint(0, width)
            y1 = random.randint(0, height)
            x2 = random.randint(0, width)
            y2 = random.randint(0, height)
            line_color = (
                random.randint(0, 255),
                random.randint(0, 255),
                random.randint(0, 255)
            )
            draw.line([(x1, y1), (x2, y2)], fill=line_color, width=random.randint(1, 2))
        
        # 添加干扰点
        for i in range(50):
            x = random.randint(0, width)
            y = random.randint(0, height)
            point_color = (
                random.randint(0, 255),
                random.randint(0, 255),
                random.randint(0, 255)
            )
            draw.point((x, y), fill=point_color)
        
        return img